package pers.cz.common.meta;

import pers.cz.common.annotation.*;
import pers.cz.common.pub.AbstractEntity;
import pers.cz.common.exception.ErrorCode;
import pers.cz.common.exception.OrmException;
import pers.cz.common.sharding.DefaultShardingStrategy;
import pers.cz.common.sharding.IShardingStrategy;
import pers.cz.common.sharding.ShardingStrategy;
import utils.ObjUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @program: Jef-orm
 * @description: 存放各种元数据信息
 * @author: Cheng Zhi
 * @create: 2023-09-03 10:04
 **/
public final class MetaHolder {

    private MetaHolder() {

    }

    public static TableMeta initTable(AbstractEntity entity) {

        Class<? extends AbstractEntity> entityClass = entity.getClass();
        Table tableAnnotation = entityClass.getAnnotation(Table.class);
        if (tableAnnotation == null || tableAnnotation.sheetName().isEmpty()) {
            throw new OrmException(ErrorCode.ORM_GET_TABLE_NAME_ERROR);
        }
        Sharding sharding = entityClass.getAnnotation(Sharding.class);

        Map<String, Column> columns = new LinkedHashMap<>();
        Map<String, Ignore> ignores = new HashMap<>();
        for (Field field : entityClass.getDeclaredFields()) {

            Column columnAnnotation = field.getAnnotation(Column.class);
            String fieldName = field.getName();
            if (columnAnnotation != null && ((columnAnnotation.name() != null && !columnAnnotation.name().isEmpty()) || (columnAnnotation.excelColumn() != null && !columnAnnotation.excelColumn().isEmpty()))) {
                columns.put(fieldName, columnAnnotation);
            } else {

                columns.put(fieldName, new Column() {

                    @Override
                    public Class<? extends Annotation> annotationType() {
                        return null;
                    }

                    @Override
                    public String name() {
                        return ObjUtils.camel2under(fieldName);
                    }

                    @Override
                    public String excelColumn() {
                        return ObjUtils.camel2under(fieldName);
                    }

                    @Override
                    public String type() {
                        return null;
                    }
                }); // 将pojo类字段转换为数据库下划线命名法
            }

            Ignore ignoreAnnotation = field.getAnnotation(Ignore.class);
            if (ignoreAnnotation != null) {
                ignores.put(fieldName, ignoreAnnotation);
            }
        }

        TableMeta tableMeta = new TableMeta();
        tableMeta.setColumns(columns);
        tableMeta.setTable(tableAnnotation);
        tableMeta.setIgnores(ignores);
        tableMeta.setSharding(sharding);
        return tableMeta;
    }
}
